/*
	自定义结构体继承 List 结构体：

	type SortList[K array.KEYS, V string|int|int8|int16|int32|int64|float32|float64] struct {
	    Desc bool
	    array.List[K,V]
	}
	type OrderList[K array.KEYS, V array.VALUES] struct {
	    Order int
	    array.List[K,V]
	}

	重写结构体方法 New() array.Arrays[K,V]  Less(i, j int) bool ：
	1、 Less(i, j int) bool 为当前数组的排序处理方法，可以根据本身的应用场景做不同的排序处理
	func (l *SortList[K,V])Less(i, j int) bool {
	    if l.Desc { return array.GetValue[K,V](l, i) > array.GetValue[K,V](l, j) }
	    return array.GetValue[K,V](l, i) < array.GetValue[K,V](l, j)
	}
	2、 结构体排序也可以根据当前结构体字段排序
	func (l *OrderList[K,V])Less(i, j int) bool {
	    var (
	        o1, o2 any
	    )
	    o1, o2 = array.GetValue[K,V](l, i), array.GetValue[K,V](l, j)
	    return o1.(*OrderList[K,V]).Order > o2.(*OrderList[K,V]).Order
	}
	3、 New() array.Arrays[K,V] 为当前结构体的对象复制时需要生成新的结构体指针
	func (l *SortList[K,V])New() array.Arrays[K,V] { return &SortList[K,V]{} }
	func (l *OrderList[K,V])New() array.Arrays[K,V] { return &OrderList[K,V]{} }

	数组排序只需要使用标准库的 sort 包；使用sort.Sort()函数即可，传入一个数组接口
*/

package array

import(
    "sync"
    "reflect"
)
type KEYS interface { string|int|int8|int16|int32|int64|float32|float64|byte }
type VALUES any

type Arrays[K KEYS, V VALUES] interface {
	ptrLen() *int
	ptrKeys() *[]K
	ptrValues() *[]V
	ptrMu() *sync.RWMutex
	copy(Arrays[K,V])
	Copy(Arrays[K,V])
	Len() int
	Swap(int, int)
	Init(map[K]V)
	// 后面的方法必须重写
	New() Arrays[K,V]
	Less(int, int) bool
}

type List[K KEYS, V VALUES] struct {
	keys 	[]K
	values 	[]V
	length 	int
	mu 		*sync.RWMutex
}

func (l *List[K,V])ptrLen() *int { if &l.length == nil { l.length = 0 }; return &l.length }
func (l *List[K,V])ptrKeys() *[]K { if &l.keys == nil { l.keys = make([]K,0) }; return &l.keys }
func (l *List[K,V])ptrValues() *[]V { if &l.values == nil { l.values = make([]V,0) }; return &l.values }
func (l *List[K,V])ptrMu() *sync.RWMutex { if l.mu == nil { l.mu = new(sync.RWMutex) }; return l.mu }
// func (l *List[K,V])IsEmpty() bool { return l.Len() == 0 }
func (l *List[K,V])Len() int { l.ptrMu().Lock(); defer l.ptrMu().Unlock(); return *(l.ptrLen()) }
func (l *List[K,V])Swap(i, j int) {
	l.ptrMu().Lock()
	defer l.ptrMu().Unlock()
	if *(l.ptrLen()) < 1 { return }
	l.keys[i], l.keys[j], l.values[i], l.values[j] = l.keys[j], l.keys[i], l.values[j], l.values[i]
}
func (l *List[K,V])Init(data map[K]V) {
	l.ptrMu().Lock()
	defer l.ptrMu().Unlock()
	keys, values, item := make([]K, len(data)), make([]V, len(data)), 0
	for k, v := range data {
		keys[item], values[item] = k,v
		item++
	}
	l.keys, l.values, l.length = keys, values, len(data)
}
// 数组复制将会把多维数组完全复制成为新的数组不影响旧数据
// 已知问题：对于底层不是 *List[K,V] 结构体的指针不做修改
func (l *List[K,V])Copy(old Arrays[K,V]) { l.copy(old) }
func (l *List[K,V])copy(old Arrays[K,V]) {
	keys, values := make([]K, *(old.ptrLen())), make([]V, *(old.ptrLen()))
	copy(keys, *(old.ptrKeys()))
	copy(values, *(old.ptrValues()))
	for k,v := range *(old.ptrValues()) {
		if CheckPtr(v) { values[k] = getValueForPtr(v).(V) } else { values[k] = v }
	}
	l.keys, l.values, l.length, l.mu = keys, values, *(old.ptrLen()), new(sync.RWMutex)
}

// 以下结构体方法必须重写
func (l *List[K,V])Less(i, j int) bool { return false }
func (l *List[K,V])New() Arrays[K,V] { return &List[K,V]{} }

// -----------------------------------------------------------------数组的泛型函数 start---------------------------------------------------

func Exist[K KEYS, V VALUES](arr Arrays[K,V], key K) (ok bool) {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	for _,v := range *(arr.ptrKeys()) { if key == v { ok = true; break } }
	return
}

func First[K KEYS, V VALUES](arr Arrays[K,V]) (key K, value V) {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	if *(arr.ptrLen()) > 0 { key, value = (*(arr.ptrKeys()))[0], (*(arr.ptrValues()))[0] }
	return
}

func Last[K KEYS, V VALUES](arr Arrays[K,V]) (key K, value V) {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	lens := *(arr.ptrLen())
	if lens > 0 { key, value = (*(arr.ptrKeys()))[lens-1], (*(arr.ptrValues()))[lens-1] }
	return
}

func Push[K KEYS, V VALUES](arr Arrays[K,V], key K, value V) (V, bool) {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	ok := true
	for k,v := range *(arr.ptrKeys()) {
		if key == v { ok = false; value = (*(arr.ptrValues()))[k]; break }
	}
	if ok {
		*(arr.ptrKeys()), *(arr.ptrValues()) = append(*(arr.ptrKeys()), key), append(*(arr.ptrValues()), value)
		*(arr.ptrLen())++
	}
	return value, ok
}

func Get[K KEYS, V VALUES](arr Arrays[K,V], key K) (value V) {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	for k,v := range *(arr.ptrKeys()) { if key == v { value = (*(arr.ptrValues()))[k]; break } }
	return
}

func Gets[K KEYS, V VALUES](arr Arrays[K,V], keys []K) map[K]V {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	data := make(map[K]V, 0)
	for _,key := range keys {
		for k,v := range *(arr.ptrKeys()) { if key == v { data[v] = (*(arr.ptrValues()))[k]; break } }
	}
	return data
}

func Set[K KEYS, V VALUES](arr Arrays[K,V], key K, value V) (ok bool) {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	for k,v := range *(arr.ptrKeys()) { if key == v { (*(arr.ptrValues()))[k], ok = value, true; break } }
	return
}

func Sets[K KEYS, V VALUES](arr Arrays[K,V], data map[K]V) map[K]V {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	lostData := make(map[K]V, len(data))
	for key,value := range data { lostData[key] = value }
	for k,v := range *(arr.ptrKeys()) {
		if len(lostData) < 1 { break }
		for key,value := range lostData {
			if key == v {
				(*(arr.ptrValues()))[k] = value
				delete(lostData, key)
				break
			}
		}
	}
	return lostData
}

func Delete[K KEYS, V VALUES](arr Arrays[K,V], key K) (value V) {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	for k,v := range *(arr.ptrKeys()) {
		if key == v { *(arr.ptrKeys()), *(arr.ptrValues()), value = append((*(arr.ptrKeys()))[:k], ((*(arr.ptrKeys()))[(k+1):])...), append((*(arr.ptrValues()))[:k], ((*(arr.ptrValues()))[(k+1):])...), (*(arr.ptrValues()))[k]; *(arr.ptrLen())--; break }
	}
	return
}

func Deletes[K KEYS, V VALUES](arr Arrays[K,V], delKeys []K) map[K]V {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	data, keys, values, offset, cloneDelKeys := make(map[K]V, 0), make([]K, *(arr.ptrLen())), make([]V, *(arr.ptrLen())), 0, make([]K, len(delKeys))
	copy(keys, *(arr.ptrKeys()))
	copy(values, *(arr.ptrValues()))
	copy(cloneDelKeys, delKeys)
	for k,v := range *(arr.ptrKeys()) {
		if len(cloneDelKeys) < 1 { break }
		for i, key := range cloneDelKeys {
			if key == v {
				data[key] = values[k-offset]
				keys, values, cloneDelKeys = append(keys[:(k-offset)], keys[(k+1-offset):]...), append(values[:(k-offset)], values[(k+1-offset):]...), append(cloneDelKeys[:i], cloneDelKeys[(i+1):]...)
				*(arr.ptrLen())--
				offset++
				break
			}
		}
	}
	*(arr.ptrKeys()), *(arr.ptrValues()) = keys, values
	return data
}

func Clear[K KEYS, V VALUES](arr Arrays[K,V]) {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	*(arr.ptrKeys()), *(arr.ptrValues()), *(arr.ptrLen()) = make([]K, 0), make([]V, 0), 0
}

func Copy[K KEYS, V VALUES](arr Arrays[K,V]) Arrays[K,V] {
	arr.ptrMu().Lock()
	defer arr.ptrMu().Unlock()
	n := arr.New()
	n.copy(arr)
	return n
}

// 返回数组值切片副本
func GetValues[K KEYS, V VALUES](arr Arrays[K,V]) []V {
	v := make([]V, *(arr.ptrLen()))
	copy(v, *(arr.ptrValues()))
	return v
}

// 返回数组键切片副本
func GetKeys[K KEYS, V VALUES](arr Arrays[K,V]) []K {
	k := make([]K, *(arr.ptrLen()))
	copy(k, *(arr.ptrKeys()))
	return k
}

// 返回数组值切片对应下标的值
func GetValue[K KEYS, V VALUES](arr Arrays[K,V], item int) (value V) {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	if *(arr.ptrLen()) > item { value = (*(arr.ptrValues()))[item] }
	return
}

// 返回数组键切片对应下标的键
func GetKey[K KEYS, V VALUES](arr Arrays[K,V], item int) (key K) {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	if *(arr.ptrLen()) > item { key = (*(arr.ptrKeys()))[item] }
	return
}

func Maps[K KEYS, V VALUES](arr Arrays[K,V]) map[K]V {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	data := make(map[K]V, *(arr.ptrLen()))
	for k,v := range *(arr.ptrValues()) {
		if CheckPtr(v) { data[(*(arr.ptrKeys()))[k]] = getValueForPtr(v).(V) } else { data[(*(arr.ptrKeys()))[k]] = v }
	}
	return data
}

// 合并数组将会把第一组之后的数组内容全部完整的复制到第一组内；相同键名的将以最后一个为准
func Merges[K KEYS, V VALUES](arrs ...Arrays[K,V]) {
	if len(arrs) > 0 {
		arrs[0].ptrMu().Lock()
		clone := arrs[0].New()
		*(clone.ptrKeys()), *(clone.ptrValues()), *(clone.ptrLen()) = *(arrs[0].ptrKeys()), *(arrs[0].ptrValues()), *(arrs[0].ptrLen())
		for i := 1; i < len(arrs); i++ {
			arrs[i].ptrMu().Lock()
			for k,v := range *(arrs[i].ptrKeys()) {
				if !Exist[K,V](clone, v) { Push[K,V](clone, v, (*(arrs[i].ptrValues()))[k]) } else { Set[K,V](clone, v, (*(arrs[i].ptrValues()))[k]) }
			}
			arrs[i].ptrMu().Unlock()
		}
		*(arrs[0].ptrKeys()), *(arrs[0].ptrValues()), *(arrs[0].ptrLen()) = *(clone.ptrKeys()), *(clone.ptrValues()), clone.Len()
		arrs[0].ptrMu().Unlock()
	}
}

// 切分数组 start 开始 size 长度
func Slice[K KEYS, V VALUES](arr Arrays[K,V], start, size int) Arrays[K,V] {
	arr.ptrMu().RLock()
	defer arr.ptrMu().RUnlock()
	n, arrLen := arr.New(), *(arr.ptrLen())
	if start < 0 { start += arrLen }
	if start < 0 || start > arrLen { start, size = arrLen, arrLen }
	if size < arrLen { size += start }
	if size > arrLen { size = arrLen }
	if size < arrLen {
		keys, values, arrKeys, arrValues, length := make([]K, size-start), make([]V, size-start), make([]K, start), make([]V, start), (size-start)
		copy(keys, (*(arr.ptrKeys()))[start:size])
		copy(values, (*(arr.ptrValues()))[start:size])
		copy(arrKeys, (*(arr.ptrKeys()))[:start])
		copy(arrValues, (*(arr.ptrValues()))[:start])
		arrKeys, arrValues = append(arrKeys, (*(arr.ptrKeys()))[size:arrLen]...), append(arrValues, (*(arr.ptrValues()))[size:arrLen]...)
		*(n.ptrKeys()), *(n.ptrValues()), *(n.ptrLen()), *(arr.ptrKeys()), *(arr.ptrValues()), *(arr.ptrLen()) = keys, values, length, arrKeys, arrValues, (arrLen-length)
	}
	return n
}
// -----------------------------------------------------------------数组的泛型函数 end---------------------------------------------------

// -----------------------------------------------------------------------工具函数-----------------------------------------------------------------

// 
func getValueForPtr(old any) any {
	l := reflect.ValueOf(old)
	New := l.MethodByName("New")
	if New.Kind() == reflect.Func {
		n := New.Call([]reflect.Value{})[0]
		Copy := n.MethodByName("Copy")
		if Copy.Kind() == reflect.Func { Copy.Call([]reflect.Value{l}) }
		return n.Interface()
	}
	// TODO
	return old
}

func CheckPtr(i any) bool { return reflect.ValueOf(i).Kind() == reflect.Ptr }
func GetTypeString(i any) string { return reflect.TypeOf(i).String() }
